package com.laogao.lesson082;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/files")
public class FileController {

    @Autowired
    private FileProperties fileProperties;

    /**
     * 多文件上传,压缩后存储
     *
     * @param files
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public ResponseEntity<String> uploadFiles(@RequestParam("files") MultipartFile[] files) throws IOException {
        if (files == null || files.length == 0) {
            return ResponseEntity.badRequest().body("No files uploaded");
        }

        // 1. 创建临时目录
        String uuid = UUID.randomUUID().toString();
        Path tempDir = Paths.get(fileProperties.getUploadPath(), uuid);
        Files.createDirectories(tempDir);

        // 2. 保存文件
        for (MultipartFile file : files) {
            Path filePath = tempDir.resolve(file.getOriginalFilename());
            file.transferTo(filePath);
        }

        // 3. 压缩文件夹为zip
        Path zipPath = Paths.get(fileProperties.getUploadPath(), uuid + ".zip");
        try (FileOutputStream fos = new FileOutputStream(zipPath.toFile());
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            Files.walk(tempDir)
                    .filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        ZipEntry zipEntry = new ZipEntry(tempDir.relativize(path).toString());
                        try {
                            zos.putNextEntry(zipEntry);
                            Files.copy(path, zos);
                            zos.closeEntry();
                        } catch (IOException e) {
                            throw new RuntimeException("Zip error", e);
                        }
                    });
        }

        // 4. 删除临时文件夹及其内容
        try {
            Files.walk(tempDir)
                    .map(Path::toFile)
                    .forEach(File::delete);
            Files.delete(tempDir);
        } catch (IOException e) {
            throw new RuntimeException("Failed to clean up temp files", e);
        }

        // 5. 返回下载 URL
        String downloadUrl = "/files/download/" + uuid;
        return ResponseEntity.ok(downloadUrl);
    }

    /**
     * localhost:8080/files/download/06eab76a-edff-40c5-b606-7e8591658de6
     * 下载压缩文件
     *
     * @param uuid
     * @param response
     * @throws IOException
     */
    @GetMapping("/download/{uuid}")
    public void downloadZip(@PathVariable String uuid, HttpServletResponse response) throws IOException {
        Path zipPath = Paths.get(fileProperties.getUploadPath(), uuid + ".zip");
        if (!Files.exists(zipPath)) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=" + uuid + ".zip");
        Files.copy(zipPath, response.getOutputStream());
        response.getOutputStream().flush();
    }
}
